﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Undsf.RmmvDbms.Data;
using Undsf.RmmvDbms.Data.Internal;
using Action = Undsf.RmmvDbms.Data.Internal.Action;

namespace Undsf.RmmvDbms
{
    class DQ1DataConverter
    {
        public IDictionary<int, Skill> Skills { get; set; }
        public IDictionary<string, int> CommandSkillIdMapping { get; set; }

        public IDictionary<int, Enemy> Enemies { get; set; }
        
        public void Convert(string path)
        {
            IWorkbook wk = new XSSFWorkbook(path);
            // Skills = CreateSkills(wk.GetSheet("技能"));
            Enemies = CreateEnemies(wk.GetSheet("怪物"));
            return;
        }

        private Skill CreateSkill(IRow row)
        {
            return null;
        }

        public IDictionary<int, Skill> CreateSkills(ISheet sheet)
        {
            return null;
        }

        private int GetSkillIdByCommand(string command)
        {
            if (CommandSkillIdMapping == null)
            {
                return Skill.SkillIdAttack;
            }

            bool commandExists = CommandSkillIdMapping.ContainsKey(command);
            if (!commandExists)
            {
                return Skill.SkillIdAttack;
            }

            return CommandSkillIdMapping[command];
        }

        private Enemy CreateEnemy(IRow row)
        {
            ICell cellId = row.GetCell(0);
            Enemy enemy = new Enemy();
            enemy.traits = new List<Trait>();

            enemy.id = (int)cellId.NumericCellValue;
            // TODO 日文名 1
            enemy.name = row.GetCell(2).StringCellValue;
            enemy.Health = (int)row.GetCell(3).NumericCellValue;
            enemy.Mana = (int)row.GetCell(4).NumericCellValue;
            enemy.PhysicsAtk = (int)row.GetCell(5).NumericCellValue;
            enemy.PhysicsDef = (int)row.GetCell(6).NumericCellValue;
            enemy.Agility = (int)row.GetCell(7).NumericCellValue;
            // 闪避 8
            int evasion = (int)(row.GetCell(8).NumericCellValue * 1000 / 16 + 0.5);  // 四舍五入，保留三位有效数字
            if (evasion > 0)
            {
                enemy.traits.Add(new Trait(Trait.CodeAppendAbility, Trait.DataIdAppendAbilityEvasion, evasion / 1000f));
            }
            
            // TODO 智力 9
            enemy.exp = (int)row.GetCell(10).NumericCellValue;
            enemy.gold = (int)row.GetCell(11).NumericCellValue;
            // TODO 魔法抗性 12 13 14
            int lightResist = Int32.Parse(row.GetCell(12).StringCellValue.Substring(0, 1));
            int sleepResist = Int32.Parse(row.GetCell(13).StringCellValue.Substring(0, 1));
            int slientResist = Int32.Parse(row.GetCell(14).StringCellValue.Substring(0, 1));
            if (lightResist > 0)
            {
                // 闪光系具有抗性
                enemy.traits.Add(new Trait(Trait.CodeElementRate, 2, (7-lightResist) / 7.0));
            }
            if (sleepResist == 7)
            {
                // 催眠状态免疫
                enemy.traits.Add(new Trait(Trait.CodeStateResist, 2, 1));
            }
            else if (sleepResist > 0)
            {
                // 催眠状态具有一定抗性
                enemy.traits.Add(new Trait(Trait.CodeStateRate, 2, (7 - sleepResist) / 7.0));
            }
            if (slientResist == 7)
            {
                // 沉默状态免疫
                enemy.traits.Add(new Trait(Trait.CodeStateResist, 3, 1));
            }
            else if (slientResist > 0)
            {
                // 沉默状态具有一定抗性
                enemy.traits.Add(new Trait(Trait.CodeStateRate, 3, (7 - slientResist) / 7.0));
            }
            // TODO 扩展魔法抗性 15 16 17

            string actMode = row.GetCell(26).StringCellValue;
            enemy.actions = new List<Action>();
            for (int i = 0; i < 8; i++) { 
                string command = row.GetCell(18 + i).StringCellValue;
                Action action = new Action(GetSkillIdByCommand(command), 5);
                if (actMode == "sequence")
                {
                    action.conditionType = Action.ConditionTypeTurn;
                    action.conditionParam1 = i + 1;
                    action.conditionParam2 = 8;
                }
                enemy.actions.Add(action);
            }

            enemy.MagicalAtk = 1;
            enemy.MagicalDef = 1;
            enemy.Luck = 1;

            return enemy;
        }

        public IDictionary<int, Enemy> CreateEnemies(ISheet sheet)
        {
            IDictionary<int, Enemy> enemies = new Dictionary<int, Enemy>();
            bool hasNextLine = true;
            int rowNum = 1;
            do
            {
                try
                {
                    IRow row = sheet.GetRow(rowNum);
                    Enemy enemy = CreateEnemy(row);
                    enemies.Add(enemy.id, enemy);
                    rowNum++;
                }
                catch (Exception ex)
                {
                    break;
                }
            } while (hasNextLine);
            return enemies;
        }
    }
}
